﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WaterLevel
{
    public partial class WaterLevelGauge : UserControl
    {
        // 水位范围属性
        [Category("Water Level")]
        [Description("水位显示的最小值")]
        [DefaultValue(0f)]
        public float MinValue { get; set; } = 0f;

        [Category("Water Level")]
        [Description("水位显示的最大值")]
        [DefaultValue(100f)]
        public float MaxValue { get; set; } = 100f;

        // 当前水位值
        private float _waterLevel = 50f;
        [Category("Water Level")]
        [Description("当前水位值")]
        [DefaultValue(50f)]
        public float WaterLevel
        {
            get => _waterLevel;
            set
            {
                _waterLevel = value;
                Invalidate();
            }
        }

        // 报警区域设置
        [Category("Alarm Settings")]
        [Description("高报警阈值")]
        [DefaultValue(80f)]
        public float HighAlarm { get; set; } = 80f;

        [Category("Alarm Settings")]
        [Description("低报警阈值")]
        [DefaultValue(20f)]
        public float LowAlarm { get; set; } = 20f;

        // 颜色设置
        [Category("Appearance")]
        [Description("正常水位颜色")]
        public Color NormalColor { get; set; } = Color.DodgerBlue;

        [Category("Appearance")]
        [Description("报警水位颜色")]
        public Color AlarmColor { get; set; } = Color.Red;

        [Category("Appearance")]
        [Description("背景颜色")]
        public Color BackgroundColor { get; set; } = Color.White;

        [Category("Appearance")]
        [Description("刻度颜色")]
        public Color ScaleColor { get; set; } = Color.Black;

        [Category("Appearance")]
        [Description("标题")]
        public string Title { get; set; } = "汽包水位";

        [Category("Appearance")]
        [Description("单位")]
        public string Unit { get; set; } = "mm";


        // 构造函数
        public WaterLevelGauge()
        {
            InitializeComponent();
            DoubleBuffered = true;
            Size = new Size(150, 300);
            Font = new Font("Arial", 8);
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            Graphics g = e.Graphics;
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

            // 绘制背景
            //g.Clear(BackgroundColor);

            // 计算尺寸
            int margin = 10;
            int bottomMargin = 25;
            int leftMargin = 35; // 左侧留出刻度空间
            int rightMargin = 25; // 右侧留出刻度空间
            int width = Width - rightMargin - leftMargin;
            int height = Height - margin - bottomMargin;
            Rectangle mainRect = new Rectangle(leftMargin, margin, width, height);

            // 绘制外框
            g.DrawRectangle(Pens.Black, mainRect);

            // 绘制标题
            /*using (var titleFont = new Font("Segoe UI", 8, FontStyle.Bold))
            using (var titleBrush = new SolidBrush(Color.Red))
            {
                SizeF titleSize = g.MeasureString(Title, titleFont);
                g.DrawString(Title, titleFont, titleBrush, (Width - titleSize.Width) / 2, 10);
            }*/

            // 计算水位高度 (从底部开始)
            float range = MaxValue - MinValue;
            if (range <= 0) range = 1; // 防止除零错误

            float levelFraction = (WaterLevel - MinValue) / range;
            levelFraction = Math.Max(0, Math.Min(1, levelFraction)); // 限制在0-1之间

            int waterHeight = (int)(height * levelFraction);
            int waterTop = margin + height - waterHeight;
            Rectangle waterRect = new Rectangle(leftMargin, waterTop, width, waterHeight);

            // 根据水位是否在报警区域选择颜色
            Color waterColor = (WaterLevel > HighAlarm || WaterLevel < LowAlarm)
                ? AlarmColor
                : NormalColor;

            // 绘制水位
            using (var brush = new SolidBrush(waterColor))
            {
                g.FillRectangle(brush, waterRect);
            }

            // 绘制刻度
            DrawScales(g, leftMargin, margin, width, height);

            // 绘制报警区域标记
            DrawAlarmMarkers(g, leftMargin, margin, height, width);

            // 绘制当前值
            DrawCurrentValue(g, leftMargin, width, height);
        }

        private void DrawScales(Graphics g, int leftMargin, int margin, int width, int height)
        {
            int scaleWidth = 5;
            int textMargin = 5;
            int tickCount = 10; // 刻度数量

            using (var scalePen = new Pen(ScaleColor))
            using (var textBrush = new SolidBrush(ScaleColor))
            {
                for (int i = 0; i <= tickCount; i++)
                {
                    // 计算刻度位置
                    float fraction = (float)i / tickCount;
                    int y = margin + (int)(height * (1 - fraction));

                    // 主刻度线
                    g.DrawLine(scalePen, leftMargin, y, leftMargin - scaleWidth, y);

                    // 刻度值 (实际值)
                    float value = MinValue + fraction * (MaxValue - MinValue);
                    string text = value.ToString("F0");
                    SizeF textSize = g.MeasureString(text, Font);

                    // 左侧刻度值
                    g.DrawString(text, Font, textBrush,
                        leftMargin - textSize.Width - textMargin,
                        y - textSize.Height / 2);
                }
            }
        }

        private void DrawAlarmMarkers(Graphics g, int leftMargin, int margin, int height, int width)
        {
            float range = MaxValue - MinValue;
            if (range <= 0) return;

            // 计算高报警位置
            float highFraction = (HighAlarm - MinValue) / range;
            highFraction = Math.Max(0, Math.Min(1, highFraction));
            int highY = margin + (int)(height * (1 - highFraction));

            // 计算低报警位置
            float lowFraction = (LowAlarm - MinValue) / range;
            lowFraction = Math.Max(0, Math.Min(1, lowFraction));
            int lowY = margin + (int)(height * (1 - lowFraction));

            // 绘制报警标记
            using (var alarmBrush = new SolidBrush(Color.FromArgb(80, AlarmColor)))
            using (var alarmPen = new Pen(AlarmColor, 1))
            {
                // 高报警线
                //g.DrawLine(alarmPen, leftMargin, highY, leftMargin + width, highY);

                // 高报警三角形
                Point[] highTriangle = {
                    new Point(leftMargin + width + 5, highY),
                    new Point(leftMargin + width + 15, highY - 5),
                    new Point(leftMargin + width + 15, highY + 5)
                };
                g.FillPolygon(alarmBrush, highTriangle);

                // 低报警线
                //g.DrawLine(alarmPen, leftMargin, lowY, leftMargin + width, lowY);

                // 低报警三角形
                Point[] lowTriangle = {
                    new Point(leftMargin + width + 5, lowY),
                    new Point(leftMargin + width + 15, lowY - 5),
                    new Point(leftMargin + width + 15, lowY + 5)
                };
                g.FillPolygon(alarmBrush, lowTriangle);

                // 报警标签
                g.DrawString("高", Font, Brushes.Red, leftMargin + width + 5, highY - 20);
                g.DrawString("低", Font, Brushes.Red, leftMargin + width + 5, lowY - 20);
            }
        }

        private void DrawCurrentValue(Graphics g, int leftMargin, int width, int height)
        {
            string text = $"{WaterLevel:F1} {Unit}";
            using (var valueFont = new Font(Font.FontFamily, 10, FontStyle.Bold))
            {
                SizeF textSize = g.MeasureString(text, valueFont);
                RectangleF rect = new RectangleF(
                    leftMargin + (width - textSize.Width) / 2,
                    height + 15,
                    textSize.Width,
                    textSize.Height);

                // 绘制背景和水位值
                using (var backBrush = new SolidBrush(Color.FromArgb(200, Color.White)))
                {
                    g.FillRectangle(backBrush, rect);
                }

                g.DrawString(text, valueFont, Brushes.Black, rect);
            }
        }
    }
}
